﻿using Abp;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.ElasticSearch;
using Abp.RemoteEventBus;
using AutoMapper.QueryableExtensions;
using FwProject.Com;
using FwProject.Com.Dto;
using FwProject.Comm;
using FwProject.Commodity.Dto;
using FwProject.EventAdvertising.Dto;
using FwProject.PublicService;
using FwProject.Shop.Dto;
using FwProject.ShopApplication;
using FwProject.ShoppingMall.BrandInfo;
using FwProject.ShoppingMall.Com;
using FwProject.ShoppingMall.Commodity;
using FwProject.ShoppingMall.EventAdvertising;
using FwProject.ShoppingMall.Product;
using FwProject.ShoppingMall.Shop;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using X.PagedList;
using static FwProject.Com.Dto.SpceEnterDto;

namespace FwProject.Shop
{
    public class ShopProductAppService : FwProjectAppServiceBase, IShopProductAppService
    {
        private readonly IRepository<ShopProduct, Guid> _repositoryShopProduct;
        private readonly IRepository<ShopType, Guid> _repositoryShopType;
        private readonly IRepository<Brand, Guid> _repositoryBrand;
        private readonly IRepository<ShopProductPic, Guid> _repositoryShopProductPic;
        private readonly IRepository<ShopProductPicDetiails, Guid> _repositoryShopProductPicDetiails;
        private readonly IRepository<ShopProductSpce, Guid> _repositoryShopProductSpce;
        private readonly IRepository<ShopProductSpceValue, Guid> _repositoryShopProductSpceValue;
        private readonly IRepository<ShopProductSku, Guid> _repositoryShopProductSku;
        private readonly IRepository<ShopProductAttr, Guid> _repositoryShopProductAttr;
        private readonly IRepository<ShopProductPar, Guid> _repositoryShopProductPar;

        private readonly IRepository<CommodityCollection, Guid> _repositoryCommodityCollection;
        private readonly IRepository<CommodityReviews, Guid> _repositoryCommodityReviews;
        private readonly IRepository<ShopOrderDetails, Guid> _repositoryShopOrderDetails;
        private readonly IRepository<ShopOrder, Guid> _repositoryShopOrder;
        private readonly IRepository<ShopProductTag, Guid> _repositoryShopProductTag;

        private readonly IRepository<ProductType, Guid> _repositoryProductType;
        private readonly IRepository<ProductType_Attr, Guid> _repositoryProductTypeAttr;
        private readonly IRepository<ProductType_Par, Guid> _repositoryProductTypePar;
        private readonly IRepository<ProductType_Parvalue, Guid> _repositoryProductTypeParvalue;
        private readonly IRepository<ProductType_Brand, Guid> _repositoryProductTypeBrand;
        private readonly IRepository<ProductTypeSpce, Guid> _repositoryProductTypeSpce;
        private readonly IRepository<Spce, Guid> _repositorySpce;
        private readonly IRepository<ProductSpcevalue, Guid> _repositoryProductSpcevalue;
        private readonly IRepository<ShopTag, Guid> _repositoryShopTag;

        private readonly IRepository<Footprint, Guid> _repositoryFootprint;


        #region app服务
        /// <summary>
        /// 评论服务
        /// </summary>
        private readonly ICommodityReviewsAppService _commodityReviewsAppService;
        /// <summary>
        /// 购物车服务
        /// </summary>
        private readonly IShopCarAppService _shopCarAppService;
        /// <summary>
        /// 收藏服务
        /// </summary>
        private readonly ICommodityCollectionAppService _commodityCollectionAppService;
        private readonly IShopSecondkillAppService _shopSecondkillAppService;


        #endregion

        /// <summary>
        /// 搜索引擎
        /// </summary>
        private readonly IElasticsearch _elasticsearch;



        public IGuidGenerator _guid { get; set; }
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly IConfigurationRoot _appConfiguration;

        public ShopProductAppService(IRepository<ShopProduct, Guid> repositoryShopProduct,
            IRepository<ShopType, Guid> repositoryShopType,
            IRepository<Brand, Guid> repositoryBrand,
            IRepository<ShopProductPic, Guid> repositoryShopProductPic,
            IRepository<ShopProductPicDetiails, Guid> repositoryShopProductPicDetiails,

            IRepository<ProductType, Guid> repositoryProductType,
            IRepository<ProductType_Attr, Guid> repositoryProductTypeAttr,
            IRepository<ProductType_Par, Guid> repositoryProductTypePar,
            IRepository<ProductType_Parvalue, Guid> repositoryProductTypeParvalue,
            IRepository<ProductType_Brand, Guid> repositoryProductTypeBrand,
            IRepository<ProductTypeSpce, Guid> repositoryProductTypeSpce,
            IRepository<Spce, Guid> repositorySpce,
            IRepository<ProductSpcevalue, Guid> repositoryProductSpcevalue,
            IRepository<ShopTag, Guid> repositoryShopTag,
            IHostingEnvironment hostingEnvironment,

            IRepository<ShopProductSpce, Guid> repositoryShopProductSpce,
            IRepository<ShopProductSpceValue, Guid> repositoryShopProductSpceValue,
            IRepository<ShopProductSku, Guid> repositoryShopProductSku,
            IRepository<ShopProductAttr, Guid> repositoryShopProductAttr,
            IRepository<ShopProductTag, Guid> repositoryShopProductTag,
            IRepository<ShopProductPar, Guid> repositoryShopProductPar,

            IRepository<CommodityCollection, Guid> repositoryCommodityCollection,
            IRepository<CommodityReviews, Guid> repositoryCommodityReviews,
            IRepository<ShopOrderDetails, Guid> repositoryShopOrderDetails,
            IRepository<ShopOrder, Guid> repositoryShopOrder,
            IElasticsearch elasticsearch,
            ICommodityReviewsAppService commodityReviewsAppService,
            ICommodityCollectionAppService commodityCollectionAppService,
            IShopSecondkillAppService shopSecondkillAppService,
             IShopCarAppService shopCarAppService,
             IRepository<Footprint, Guid> repositoryFootprint
            )
        {
            _hostingEnvironment = hostingEnvironment;
            _shopCarAppService = shopCarAppService;
            _shopSecondkillAppService = shopSecondkillAppService;
            _commodityCollectionAppService = commodityCollectionAppService;
            _commodityReviewsAppService = commodityReviewsAppService;
            _elasticsearch = elasticsearch;
            _repositoryShopOrder = repositoryShopOrder;
            _repositoryShopOrderDetails = repositoryShopOrderDetails;
            _repositoryCommodityReviews = repositoryCommodityReviews;
            _repositoryCommodityCollection = repositoryCommodityCollection;
            _repositoryShopProduct = repositoryShopProduct;
            _repositoryShopType = repositoryShopType;
            _repositoryBrand = repositoryBrand;
            _repositoryShopProductPic = repositoryShopProductPic;
            _repositoryProductType = repositoryProductType;
            _repositoryProductTypeAttr = repositoryProductTypeAttr;
            _repositoryProductTypePar = repositoryProductTypePar;
            _repositoryProductTypeParvalue = repositoryProductTypeParvalue;
            _repositoryProductTypeBrand = repositoryProductTypeBrand;
            _repositoryProductTypeSpce = repositoryProductTypeSpce;
            _repositorySpce = repositorySpce;
            _repositoryProductSpcevalue = repositoryProductSpcevalue;
            _repositoryShopTag = repositoryShopTag;
            _guid = SequentialGuidGenerator.Instance;
            _appConfiguration = hostingEnvironment.GetAppConfiguration();
            _repositoryShopProductPicDetiails = repositoryShopProductPicDetiails;
            _repositoryShopProductSpce = repositoryShopProductSpce;
            _repositoryShopProductSpceValue = repositoryShopProductSpceValue;
            _repositoryShopProductSku = repositoryShopProductSku;
            _repositoryShopProductAttr = repositoryShopProductAttr;
            _repositoryShopProductTag = repositoryShopProductTag;
            _repositoryShopProductPar = repositoryShopProductPar;

            _repositoryFootprint = repositoryFootprint;

            remoteEventBus = NullRemoteEventBus.Instance;
        }
        public IRemoteEventBus remoteEventBus { get; set; }//缓存对象
        /// <summary>
        /// 获取商品列表
        /// </summary>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetCommodityLayerDataAsync(int page, int limit, string keyword, Guid? ShopTypeid, ShopProductFlag? shopProductFlag)
        {
            var shoptypes = _repositoryShopType.GetAll().Select(o => new { o.Id, o.TypeName });
            var brands = _repositoryBrand.GetAll().Select(o => new { o.Id, o.BrandName });
            var shopProductPics = _repositoryShopProductPic.GetAll().Select(o => new { o.ShopProductid, o.PicUrl });
            var query = _repositoryShopProduct.GetAll().Join(shoptypes, s => s.ShopTypeid,
                type => type.Id, (s1, t1) => new
                {
                    s1.Id,
                    t1.TypeName,
                    s1.ProductName,
                    s1.ProductNumber,
                    s1.SpcemarketPrice,
                    s1.IsGrounding,
                    s1.Brandid,
                    s1.ImagePic,
                    s1.CreationTime,
                    s1.ShopProductFlag,
                    TypeId = t1.Id
                }).GroupJoin(brands, s => s.Brandid, b => b.Id, (s1, b1) => new ShopProductOutputDto
                {
                    Id = s1.Id,
                    Category = s1.TypeName,
                    ProductName = s1.ProductName,
                    ProductNumber = s1.ProductNumber,
                    SpcemarketPrice = s1.SpcemarketPrice,
                    IsGrounding = s1.IsGrounding ? "是" : "否",
                    ImagePic = s1.ImagePic,
                    Brands = b1.DefaultIfEmpty().FirstOrDefault().BrandName,
                    CreationTime = s1.CreationTime,
                    ShopProductFlag=s1.ShopProductFlag,
                    TypeId = s1.TypeId
                });

            if (!string.IsNullOrWhiteSpace(keyword))
                query = query.Where(o => o.ProductName.Contains(keyword));

            if (ShopTypeid.HasValue && ShopTypeid != Guid.Empty)
            {
                var ids = _repositoryShopType.GetAll().Where(o => o.Parentid == ShopTypeid.Value).Select(o=>o.Id).ToList();
                if (ids.Any())
                {
                    ids.Add(ShopTypeid.Value);
                    query = query.Where(o => ids.Any(s => s == o.TypeId));
                }
                else
                {
                    query = query.Where(o => o.TypeId == ShopTypeid.Value);
                }
            }
                

            if (shopProductFlag.HasValue)
                query = query.Where(o => o.ShopProductFlag == shopProductFlag.Value);

            var pagelist = await query.OrderByDescending(o => o.CreationTime).ToPagedListAsync(page, limit);

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = pagelist;
            dto.Count = pagelist.TotalItemCount;
            return dto;
        }
        /// <summary>
        /// 商品列表导出
        /// </summary>
        /// <returns></returns>
        public async Task<List<ShopProductOutputDto>> GetExportCommodityDataAsync(string keyword, Guid? ShopTypeid)
        {
            var shoptypes = _repositoryShopType.GetAll().Select(o => new { o.Id, o.TypeName });
            var brands = _repositoryBrand.GetAll().Select(o => new { o.Id, o.BrandName });
            var shopProductPics = _repositoryShopProductPic.GetAll().Select(o => new { o.ShopProductid, o.PicUrl });
            var query = _repositoryShopProduct.GetAll().Join(shoptypes, s => s.ShopTypeid,
                type => type.Id, (s1, t1) => new
                {
                    s1.Id,
                    t1.TypeName,
                    s1.ProductName,
                    s1.ProductNumber,
                    s1.SpcemarketPrice,
                    s1.IsGrounding,
                    s1.Brandid,
                    s1.ImagePic,
                    s1.CreationTime,
                    TypeId = t1.Id
                }).GroupJoin(brands, s => s.Brandid, b => b.Id, (s1, b1) => new ShopProductOutputDto
                {
                    Id = s1.Id,
                    Category = s1.TypeName,
                    ProductName = s1.ProductName,
                    ProductNumber = s1.ProductNumber,
                    SpcemarketPrice = s1.SpcemarketPrice,
                    IsGrounding = s1.IsGrounding ? "是" : "否",
                    ImagePic = s1.ImagePic,
                    Brands = b1.DefaultIfEmpty().FirstOrDefault().BrandName,
                    CreationTime = s1.CreationTime,
                    TypeId = s1.TypeId
                });

            if (!string.IsNullOrWhiteSpace(keyword))
                query = query.Where(o => o.ProductName.Contains(keyword));

            if (ShopTypeid.HasValue && ShopTypeid != Guid.Empty)
                query = query.Where(o => o.TypeId == ShopTypeid.Value);

            return await query.OrderByDescending(o => o.CreationTime).ToListAsync();

        }

        /// <summary>
        /// 获取新增商品前5条数据
        /// </summary>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetNewAddCommodityAsync()
        {
            var shoptypes = _repositoryShopType.GetAll().Select(o => new { o.Id, o.TypeName });
            var brands = _repositoryBrand.GetAll().Select(o => new { o.Id, o.BrandName });
            var shopProductPics = _repositoryShopProductPic.GetAll().Select(o => new { o.ShopProductid, o.PicUrl });
            var query = _repositoryShopProduct.GetAll().Join(shoptypes, s => s.ShopTypeid,
                type => type.Id, (s1, t1) => new
                {
                    s1.Id,
                    t1.TypeName,
                    s1.ProductName,
                    s1.ProductNumber,
                    s1.SpcemarketPrice,
                    s1.IsGrounding,
                    s1.Brandid,
                    s1.ImagePic,
                    TypeId = t1.Id
                }).GroupJoin(brands, s => s.Brandid, b => b.Id, (s1, b1) => new ShopProductOutputDto
                {
                    Id = s1.Id,
                    Category = s1.TypeName,
                    ProductName = s1.ProductName,
                    ProductNumber = s1.ProductNumber,
                    SpcemarketPrice = s1.SpcemarketPrice,
                    IsGrounding = s1.IsGrounding ? "是" : "否",
                    ImagePic = s1.ImagePic,
                    Brands = b1.DefaultIfEmpty().FirstOrDefault().BrandName,
                    TypeId = s1.TypeId
                });

            var list = await query.OrderByDescending(o => o.Id).Take(5).ToListAsync();

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = list;
            return dto;
        }

        public async Task<IPagedList<ShopProductOutputDto>> GetPageListAsync(int page, int limit, string keyword)
        {
            var shoptypes = _repositoryShopType.GetAll().Select(o => new { o.Id, o.TypeName });
            var brands = _repositoryBrand.GetAll().Select(o => new { o.Id, o.BrandName });
            var shopProductPics = _repositoryShopProductPic.GetAll().Select(o => new { o.ShopProductid, o.PicUrl });
            var query = _repositoryShopProduct.GetAll().Join(shoptypes, s => s.ShopTypeid,
                type => type.Id, (s1, t1) => new
                {
                    s1.Id,
                    t1.TypeName,
                    s1.ProductName,
                    s1.ProductNumber,
                    s1.SpcemarketPrice,
                    s1.Brandid,
                    s1.ImagePic,
                    TypeId = t1.Id
                }).GroupJoin(brands, s => s.Brandid, b => b.Id, (s1, b1) => new ShopProductOutputDto
                {
                    Id = s1.Id,
                    Category = s1.TypeName,
                    ProductName = s1.ProductName,
                    ProductNumber = s1.ProductNumber,
                    SpcemarketPrice = s1.SpcemarketPrice,
                    ImagePic = s1.ImagePic,
                    Brands = b1.DefaultIfEmpty().FirstOrDefault().BrandName,
                    TypeId = s1.TypeId
                });

            if (!string.IsNullOrWhiteSpace(keyword))
                query = query.Where(o => o.ProductName.Contains(keyword));

            var pagelist = await query.OrderByDescending(o => o.Id).ToPagedListAsync(page, limit);

            return pagelist;
        }

        public async Task<ShopProductCreateDto> GetCreateDtoAsync(Guid typeId)
        {
            ShopProductCreateDto dto = new ShopProductCreateDto { ShopTypeid = typeId };
            var shoptype = await _repositoryShopType.GetAsync(typeId);
            var producttype = _repositoryProductType.GetAll().Where(o => o.Id == shoptype.ProductTypeid);

            var query = producttype.GroupJoin(_repositoryProductTypeAttr.GetAll(), i => i.Id, j => j.ProductTypeid, (type, attr) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                Attrs = attr.Select(o => new ProductTypeAttrDto { AttrName = o.AttrName, Attrvalue = o.Attrvalue, Unit = o.Unit }).ToList()
            }).GroupJoin(_repositoryProductTypeBrand.GetAll(), i => i.Id, j => j.ProductTypeid, (type, proBrand) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                Brands = proBrand.Select(o => o.ProductTypebrandid).Join(_repositoryBrand.GetAll(), i => i, j => j.Id,
                (probid, brand) => new ProductTypeBrandDto
                {
                    BrandId = brand.Id,
                    BrandName = brand.BrandName
                })
            }).GroupJoin(_repositoryProductTypeSpce.GetAll(), i => i.Id, j => j.ProductTypeid, (type, proSpce) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                type.Brands,
                Spces = proSpce.Select(o => o.SpceId).Join(_repositorySpce.GetAll(), i => i, j => j.Id, (proSpceid, spce) => new
                {
                    spce.Id,
                    spce.SpceName,
                    spce.SpceNote,
                    spce.SpceType,
                }).GroupJoin(_repositoryProductSpcevalue.GetAll(), i => i.Id, j => j.ProductSpceid, (spce, spvalus) => new ProductSpceDto
                {
                    Id = spce.Id,
                    SpceName = spce.SpceName,
                    SpceNote = spce.SpceNote,
                    SpceType = spce.SpceType,
                    SpceValues = spvalus.Select(o => new SpceValuesDto() { Spcevalue = o.Spcevalue, Spcevalueico = o.Spcevalueico, Id = o.Id })
                }).ToList()
            }).GroupJoin(_repositoryProductTypePar.GetAll(), i => i.Id, j => j.ProductTypeid, (type, par) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                type.Brands,
                type.Spces,
                Pars = par.Select(o => new { o.Id, o.GroupName }).GroupJoin(_repositoryProductTypeParvalue.GetAll(), i => i.Id, j => j.ProductTypeparid,
                (group, valus) => new ProductTypeParDto
                {
                    GroupName = group.GroupName,
                    ParValus = valus.Select(o => o.Parvalue).ToList()
                }).ToList()
            });
            var first = query.Select(o => new ProductTypeDto { Isflagattr = o.Isflagattr, Ispro = o.Ispro, Isbrand = o.Isbrand, IsSpec = o.IsSpec, Attrs = o.Attrs, Pars = o.Pars, Brands = o.Brands, Spces = o.Spces }).FirstOrDefault();

            var tags = await _repositoryShopTag.GetAll().Where(o => o.IsActive).OrderByDescending(o => o.CreationTime).ProjectTo<ShopTagDto>().ToListAsync();

            dto.ProductType = first;
            dto.ShopTags = tags;
            return dto;

        }

        public async Task<ShopProductEditDto> GetEditDtoAsync(Guid id)
        {
            var entity = await _repositoryShopProduct.GetAsync(id);
            var shoptype = await _repositoryShopType.GetAsync(entity.ShopTypeid);
            var query = _repositoryProductType.GetAll().Where(o => o.Id == shoptype.ProductTypeid).GroupJoin(_repositoryProductTypeAttr.GetAll(), i => i.Id, j => j.ProductTypeid, (type, attr) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                Attrs = attr.Select(o => new ProductTypeAttrDto { AttrName = o.AttrName, Attrvalue = o.Attrvalue, Unit = o.Unit }).ToList()
            }).GroupJoin(_repositoryProductTypeBrand.GetAll(), i => i.Id, j => j.ProductTypeid, (type, proBrand) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                Brands = proBrand.Select(o => o.ProductTypebrandid).Join(_repositoryBrand.GetAll(), i => i, j => j.Id,
                (probid, brand) => new ProductTypeBrandDto
                {
                    BrandId = brand.Id,
                    BrandName = brand.BrandName
                })
            }).GroupJoin(_repositoryProductTypeSpce.GetAll(), i => i.Id, j => j.ProductTypeid, (type, proSpce) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                type.Brands,
                Spces = proSpce.Select(o => o.SpceId).Join(_repositorySpce.GetAll(), i => i, j => j.Id, (proSpceid, spce) => new
                {
                    spce.Id,
                    spce.SpceName,
                    spce.SpceNote,
                    spce.SpceType,
                }).GroupJoin(_repositoryProductSpcevalue.GetAll(), i => i.Id, j => j.ProductSpceid, (spce, spvalus) => new ProductSpceDto
                {
                    Id = spce.Id,
                    SpceName = spce.SpceName,
                    SpceNote = spce.SpceNote,
                    SpceType = spce.SpceType,
                    SpceValues = spvalus.Select(o => new SpceValuesDto() { Spcevalue = o.Spcevalue, Spcevalueico = o.Spcevalueico, Id = o.Id })
                }).ToList()
            }).GroupJoin(_repositoryProductTypePar.GetAll(), i => i.Id, j => j.ProductTypeid, (type, par) => new
            {
                type.Id,
                type.Isflagattr,
                type.Ispro,
                type.Isbrand,
                type.IsSpec,
                type.Attrs,
                type.Brands,
                type.Spces,
                Pars = par.Select(o => new { o.Id, o.GroupName }).GroupJoin(_repositoryProductTypeParvalue.GetAll(), i => i.Id, j => j.ProductTypeparid,
                (group, valus) => new ProductTypeParDto
                {
                    GroupName = group.GroupName,
                    ParValus = valus.Select(o => o.Parvalue).ToList()
                }).ToList()
            });
            var first = query.Select(o => new ProductTypeDto { Isflagattr = o.Isflagattr, Ispro = o.Ispro, Isbrand = o.Isbrand, IsSpec = o.IsSpec, Attrs = o.Attrs, Pars = o.Pars, Brands = o.Brands, Spces = o.Spces }).FirstOrDefault();

            var tags = await _repositoryShopTag.GetAll().Where(o => o.IsActive).OrderByDescending(o => o.CreationTime).ProjectTo<ShopTagDto>().ToListAsync();

            ShopProductEditDto dto = entity.MapTo<ShopProductEditDto>();

            dto.ProductType = first;
            dto.ShopTags = tags;

            //规格
            dto.ShopProductSpces = _repositoryShopProductSpce.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductSpceDto>().ToList();
            //规格值
            dto.ShopProductSpceValues = _repositoryShopProductSpceValue.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductSpceValueDto>().ToList();
            //SKU
            dto.ShopProductSkus = _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductSkuDto>().ToList();
            foreach (var item in dto.ShopProductSkus)
            {
                if (!string.IsNullOrEmpty(item.SpaceValueid))
                {
                    var vaids = item.SpaceValueid.Split('|');
                    item.SpaceValues = await _repositoryProductSpcevalue.GetAll().Where(o => vaids.Any(s => new Guid(s) == o.Id)).ProjectTo<ProductSpcevalueDto>().ToListAsync();
                }
            }

            //属性值
            dto.ShopProductAttrs = _repositoryShopProductAttr.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductAttrDto>().ToList();
            //参数
            dto.ShopProductPars = _repositoryShopProductPar.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductParDto>().ToList();
            //标签
            dto.ShopProductTags = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == dto.Id).OrderByDescending(o => o.CreationTime).ProjectTo<ShopProductTagDto>().ToList();
            //宣传图
            dto.PicImages = new List<ShopProductImagesDto>();
            var pirimg = _repositoryShopProductPic.GetAll().Where(o => o.ShopProductid == dto.Id).OrderBy(o=>o.Sequence).ToList();
            foreach (var item in pirimg)
            {
                var s = item.PicUrl.Split('/');
                dto.PicImages.Add(new ShopProductImagesDto { Path = item.PicUrl, FileName = s[s.Length - 1] });
            }
            //详情图
            dto.DetailsImages = new List<ShopProductImagesDto>();
            var detaimg = _repositoryShopProductPicDetiails.GetAll().Where(o => o.ShopProductid == dto.Id).OrderBy(o=>o.Sequence).ToList();

            foreach (var item in detaimg)
            {
                var s = item.PicUrl.Split('/');
                dto.DetailsImages.Add(new ShopProductImagesDto { Path = item.PicUrl, FileName = s[s.Length - 1] });
            }

            return dto;


        }

        public ShopProductDto GetById(Guid id)
        {
            var entity = _repositoryShopProduct.Get(id);
            var dto = entity.MapTo<ShopProductDto>();
            return dto;
        }

        /// <summary>
        /// 后台-获取选择结果
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public SearchSuggestDto GetSearchSuggestData(string keyword)
        {
            var query = _repositoryShopProduct.GetAll();

            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(o => o.ProductName.Contains(keyword) || o.ProductNumber.Contains(keyword));

            SearchSuggestDto dto = new SearchSuggestDto();
            dto.Data = query.Select(o => new SearchData { Id = o.Id.ToString(), Word = o.ProductName, Description = o.ProductNumber }).ToList();
            return dto;
        }

        public async Task<Guid> CreateAsync(ShopProductEnterDto input)
        {
            if (string.IsNullOrEmpty(input.ProductDetails))
            {
                input.ProductDetails = "<p></p>";
            }


            var entity = input.MapTo<ShopProduct>();
            entity.Id = _guid.Create();

            if (input.ShopBrandId.HasValue)
                entity.Brandid = input.ShopBrandId;

            string FileTempPath = _appConfiguration["FileServicePath:TempCommodity"];
            string FileSavaPath = _appConfiguration["FileServicePath:SavaCommodity:SavaFilePath"];
            var path = SaveFile(input.ImagePic, FileTempPath, FileSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
            entity.ImagePic = _appConfiguration["FileServicePath:SavaCommodity:Virtual"] + path;

            var id = await _repositoryShopProduct.InsertAndGetIdAsync(entity);

            #region 宣传图
            if (input.PropagandaImgs.Count > 0)
            {

                string PropagandaTempPath = _appConfiguration["FileServicePath:TempCommodityPropaganda"];
                string PropagandaSavaPath = _appConfiguration["FileServicePath:SavaCommodityPropaganda:SavaFilePath"];
                foreach (var item in input.PropagandaImgs)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        ShopProductPic pic = new ShopProductPic();
                        pic.Id = _guid.Create();
                        var propagandaPath = SaveFile(item, PropagandaTempPath, PropagandaSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
                        pic.PicUrl = _appConfiguration["FileServicePath:SavaCommodityPropaganda:Virtual"] + propagandaPath;
                        pic.ShopProductid = id;

                        pic.Sequence = input.PropagandaImgs.IndexOf(item);

                        await _repositoryShopProductPic.InsertAsync(pic);
                    }
                }
            }
            #endregion

            #region 详情图
            if (input.DetailsImgs.Count > 0)
            {
                string detailsTempPath = _appConfiguration["FileServicePath:TempCommodityDetails"];
                string detailsSavaPath = _appConfiguration["FileServicePath:SavaCommodityDetails:SavaFilePath"];
                foreach (var item in input.DetailsImgs)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        ShopProductPicDetiails pic = new ShopProductPicDetiails();
                        pic.Id = _guid.Create();
                        var propagandaPath = SaveFile(item, detailsTempPath, detailsSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
                        pic.PicUrl = _appConfiguration["FileServicePath:SavaCommodityDetails:Virtual"] + propagandaPath;
                        pic.ShopProductid = id;

                        pic.Sequence = input.DetailsImgs.IndexOf(item);

                        await _repositoryShopProductPicDetiails.InsertAsync(pic);
                    }
                }
            }
            #endregion

            #region 规格
            if (input.Specs != null && input.Specs.Count > 0)
            {
                var specids = input.Specs[0].Specids.Split("|");
                List<ShopProductSpceValue> list1 = new List<ShopProductSpceValue>();
                foreach (var item in specids)
                {
                    ShopProductSpce shopProductSpce = new ShopProductSpce();
                    shopProductSpce.Id = _guid.Create();
                    shopProductSpce.ShopProductid = id;
                    shopProductSpce.Spaceid = new Guid(item);
                    await _repositoryShopProductSpce.InsertAsync(shopProductSpce);

                }

                foreach (var item in input.Specs)
                {
                    var spcevids = item.Specvids.Split("|");
                    if (spcevids.Length > 0)
                    {
                        for (int i = 0; i < spcevids.Length; i++)
                        {
                            ShopProductSpceValue shopProductSpceValue = new ShopProductSpceValue();
                            shopProductSpceValue.ShopProductid = id;
                            shopProductSpceValue.SpaceValueid = new Guid(spcevids[i]);
                            shopProductSpceValue.Spaceid = new Guid(specids[i]);
                            list1.Add(shopProductSpceValue);
                        }
                    }

                    ShopProductSku sku = new ShopProductSku()
                    {
                        Id = _guid.Create(),
                        ShopProductid = id,
                        SpaceValueid = item.Specvids,
                        SpaceValueName = item.SpecvNames,
                        SpceCostPrice = item.Cost,
                        SpceMarketPrice = item.Price,
                        SpceWeight = item.Weight,

                    };
                    await _repositoryShopProductSku.InsertAsync(sku);
                }

                list1 = list1.Distinct(new FwProject.Comm.ListCompare<ShopProductSpceValue>((x, y) => x.Spaceid == y.Spaceid && x.SpaceValueid == y.SpaceValueid)).ToList();

                foreach (var item in list1)
                {
                    item.Id = _guid.Create();
                    await _repositoryShopProductSpceValue.InsertAsync(item);
                }
            }
            #endregion

            #region 属性
            if (input.Attrs != null)
            {
                foreach (var item in input.Attrs)
                {
                    if (!string.IsNullOrEmpty(item.Attrkey) && !string.IsNullOrEmpty(item.Attrvalue))
                    {
                        ShopProductAttr attr = new ShopProductAttr()
                        {
                            Id = _guid.Create(),
                            ShopProductid = id,
                            AttrKey = item.Attrkey,
                            AttrValue = item.Attrvalue
                        };

                        await _repositoryShopProductAttr.InsertAndGetIdAsync(attr);
                    }
                }
            }

            #endregion

            #region 参数
            if (input.ParsGroups != null)
            {
                foreach (var item in input.ParsGroups)
                {
                    if (item.ParsValues != null)
                    {
                        foreach (var i in item.ParsValues)
                        {
                            if (!string.IsNullOrEmpty(i.ParsValue))
                            {
                                ShopProductPar par = new ShopProductPar
                                {
                                    Id = _guid.Create(),
                                    ParKey = i.ParsKey,
                                    ParValue = i.ParsValue,
                                    ShopProductid = id
                                };
                                await _repositoryShopProductPar.InsertAsync(par);
                            }
                        }
                    }
                }
            }
            #endregion

            #region 标签
            if (!string.IsNullOrEmpty(input.Tags))
            {
                var tags = input.Tags.Split('|');
                foreach (var item in tags)
                {
                    ShopProductTag tag = new ShopProductTag
                    {
                        Id = _guid.Create(),
                        Tagid = new Guid(item),
                        ShopProductid = id,
                    };
                    await _repositoryShopProductTag.InsertAsync(tag);
                }
            }
            #endregion
            return id;
        }


        public async Task ModifyAsync(Guid id, ShopProductEnterDto input)
        {
            if (string.IsNullOrEmpty(input.ProductDetails))
            {
                input.ProductDetails = "<p></p>";
            }
            var entity = await _repositoryShopProduct.GetAsync(id);
            var original = entity.ImagePic;
            input.MapTo(entity);

            entity.Brandid = input.ShopBrandId;

            if (!input.ImagePic.Contains("uploads"))
            {
                string FileTempPath = _appConfiguration["FileServicePath:TempCommodity"];
                string FileSavaPath = _appConfiguration["FileServicePath:SavaCommodity:SavaFilePath"];
                var path = SaveFile(input.ImagePic, FileTempPath, FileSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/", original);
                entity.ImagePic = _appConfiguration["FileServicePath:SavaCommodity:Virtual"] + path;
            }

            await _repositoryShopProduct.UpdateAsync(entity);

            #region 宣传图
            //获取已保存的宣传图
            var originalpicImg = _repositoryShopProductPic.GetAll().Where(o => o.ShopProductid == id).ToList();
            List<string> originalpicPath = new List<string>();
            foreach (var item in originalpicImg)
            {
                var l = item.PicUrl.Split('/');
                originalpicPath.Add(l[l.Length - 1]);
            }

            //进行比对获取删除的宣传图
            var removespicImg = originalpicPath.Where(o => input.PropagandaImgs.Any(s => o == s) == false).ToList();
            if (removespicImg?.Count > 0)
            {
                for (int i = 0; i < removespicImg.Count; i++)
                {
                    var img = originalpicImg.Where(o => o.PicUrl.Contains(removespicImg[i])).FirstOrDefault();
                    //执行删除
                    if (img != null)
                        await _repositoryShopProductPic.DeleteAsync(img);
                }
            }

            //进行比对获取新增的宣传图
            var addpicImgs = input.PropagandaImgs.Where(r => originalpicPath.Any(o => o == r) == false).ToList();
            string PropagandaTempPath = _appConfiguration["FileServicePath:TempCommodityPropaganda"];
            string PropagandaSavaPath = _appConfiguration["FileServicePath:SavaCommodityPropaganda:SavaFilePath"];
            foreach (var item in addpicImgs)
            {
                if (!string.IsNullOrEmpty(item))
                {
                    var propagandaPath = SaveFile(item, PropagandaTempPath, PropagandaSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
                    ShopProductPic pic = new ShopProductPic
                    {
                        Id = _guid.Create(),
                        PicUrl = _appConfiguration["FileServicePath:SavaCommodityPropaganda:Virtual"] + propagandaPath,
                        ShopProductid = id,
                        Sequence=input.PropagandaImgs.IndexOf(item)
                    };
                    await _repositoryShopProductPic.InsertAsync(pic);
                }
            }

            //已存在下标更新
            var alreadyPic= originalpicImg.Where(o => input.PropagandaImgs.Any(s => o.PicUrl.Contains(s))).ToList();
            foreach (var item in alreadyPic)
            {
                var l = item.PicUrl.Split('/');

                var index = input.PropagandaImgs.IndexOf(l[l.Length - 1]);
                if (item.Sequence!= index)
                {
                    item.Sequence = index;
                    await _repositoryShopProductPic.UpdateAsync(item);
                }
            }

            #endregion

            #region 详情图
            var originaldeliImg = _repositoryShopProductPicDetiails.GetAll().Where(o => o.ShopProductid == id).ToList();
            List<string> originaldeliPath = new List<string>();
            foreach (var item in originaldeliImg)
            {
                var l = item.PicUrl.Split('/');
                originaldeliPath.Add(l[l.Length - 1]);
            }
            var removesdeliImg = originaldeliPath.Where(o => input.DetailsImgs.Any(s => o == s) == false).ToList();
            if (removesdeliImg?.Count > 0)
            {
                for (int i = 0; i < removesdeliImg.Count; i++)
                {
                    var img = originaldeliImg.Where(o => o.PicUrl.Contains(removesdeliImg[i])).FirstOrDefault();
                    //执行删除
                    if (img != null)
                        await _repositoryShopProductPicDetiails.DeleteAsync(img);
                }
            }

            var adddeliImgs = input.DetailsImgs.Where(r => originaldeliPath.Any(o => o == r) == false).ToList();
            string detailsTempPath = _appConfiguration["FileServicePath:TempCommodityDetails"];
            string detailsSavaPath = _appConfiguration["FileServicePath:SavaCommodityDetails:SavaFilePath"];
            foreach (var item in adddeliImgs)
            {
                if (!string.IsNullOrEmpty(item))
                {
                    var propagandaPath = SaveFile(item, detailsTempPath, detailsSavaPath, $"{DateTime.Now.ToString("yyyyMMdd")}/");
                    ShopProductPicDetiails pic = new ShopProductPicDetiails
                    {
                        Id = _guid.Create(),
                        PicUrl = _appConfiguration["FileServicePath:SavaCommodityDetails:Virtual"] + propagandaPath,
                        ShopProductid = id,
                        Sequence = input.DetailsImgs.IndexOf(item)
                    };
                    await _repositoryShopProductPicDetiails.InsertAsync(pic);
                }
            }

            //已存在下标更新
            var alreadydeli = originaldeliImg.Where(o => input.DetailsImgs.Any(s => o.PicUrl.Contains(s))).ToList();
            foreach (var item in alreadydeli)
            {
                var l = item.PicUrl.Split('/');
                var index = input.DetailsImgs.IndexOf(l[l.Length - 1]);
                if (item.Sequence != index)
                {
                    item.Sequence = index;
                    await _repositoryShopProductPicDetiails.UpdateAsync(item);
                }
            }

            #endregion

            #region 规格
            //获取已保存的商品绑定规格信息
            var originalspec = _repositoryShopProductSpce.GetAll().Where(o => o.ShopProductid == id);

            if (input.Specs != null && input.Specs.Count > 0)
            {
                var specids = input.Specs[0].Specids.Split("|");

                //进行比对获取要删除的商品绑定规格信息
                var removesSpec = originalspec.Where(o => specids.Any(s => o.Spaceid == new Guid(s)) == false).ToList();
                //进行删除
                if (removesSpec?.Count > 0)
                {
                    for (int i = 0; i < removesSpec.Count; i++)
                    {
                        await _repositoryShopProductSpce.DeleteAsync(removesSpec[i]);
                    }
                }

                //比对获取要增加的商品绑定规格信息
                var addSpecs = specids.Where(o => originalspec.Any(s => s.Spaceid == new Guid(o)) == false).ToList();
                foreach (var item in addSpecs)
                {
                    ShopProductSpce shopProductSpce = new ShopProductSpce();
                    shopProductSpce.Id = _guid.Create();
                    shopProductSpce.ShopProductid = id;
                    shopProductSpce.Spaceid = new Guid(item);
                    await _repositoryShopProductSpce.InsertAsync(shopProductSpce);
                }

                //获取传入的所有规格值Id
                List<ShopProductSpceValue> list1 = new List<ShopProductSpceValue>();
                foreach (var item in input.Specs)
                {
                    var spcevids = item.Specvids.Split("|");
                    if (spcevids.Length > 0)
                    {
                        for (int i = 0; i < spcevids.Length; i++)
                        {
                            ShopProductSpceValue shopProductSpceValue = new ShopProductSpceValue();
                            shopProductSpceValue.ShopProductid = id;
                            shopProductSpceValue.SpaceValueid = new Guid(spcevids[i]);
                            shopProductSpceValue.Spaceid = new Guid(specids[i]);
                            list1.Add(shopProductSpceValue);
                        }
                    }
                }
                //进行去重
                list1 = list1.Distinct(new FwProject.Comm.ListCompare<ShopProductSpceValue>((x, y) => x.Spaceid == y.Spaceid && x.SpaceValueid == y.SpaceValueid)).ToList();
                //获取已绑定的规格值
                var originalShecvalue = _repositoryShopProductSpceValue.GetAll().Where(o => o.ShopProductid == id);

                //进行比对获取需删除的绑定规格值
                var removeShecvalue = originalShecvalue.Where(o => list1.Any(s => s.SpaceValueid == o.SpaceValueid) == false).ToList();
                if (removeShecvalue?.Count > 0)
                {
                    for (int i = 0; i < removeShecvalue.Count; i++)
                    {
                        await _repositoryShopProductSpceValue.DeleteAsync(removeShecvalue[i]);
                    }
                }
                //进行比对获取新增的绑定规格值
                var addShecvalue = list1.Where(o => originalShecvalue.Any(s => s.SpaceValueid == o.SpaceValueid) == false).ToList();

                foreach (var item in addShecvalue)
                {
                    item.Id = _guid.Create();
                    await _repositoryShopProductSpceValue.InsertAsync(item);
                }


                //已绑定商品SKU信息
                var originalSku = _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == id);

                //进行比对获取删除的SKU
                var removeSku = originalSku.Where(o => input.Specs.Any(s => s.Id == o.Id) == false).ToList();
                if (removeSku?.Count > 0)
                {
                    for (int i = 0; i < removeSku.Count; i++)
                    {
                        await _repositoryShopProductSku.DeleteAsync(removeSku[i]);
                    }
                }

                //进行比对获取新增的SKU
                var addSkus = input.Specs.Where(o => originalSku.Any(s => s.Id == o.Id) == false).ToList();
                if (addSkus?.Count > 0)
                {
                    foreach (var item in addSkus)
                    {
                        ShopProductSku sku = new ShopProductSku()
                        {
                            Id = _guid.Create(),
                            ShopProductid = id,
                            SpaceValueid = item.Specvids,
                            SpaceValueName = item.SpecvNames,
                            SpceCostPrice = item.Cost,
                            SpceMarketPrice = item.Price,
                            SpceWeight = item.Weight
                        };
                        await _repositoryShopProductSku.InsertAsync(sku);
                    }
                }


                foreach (var item in input.Specs)
                {
                    if (item.Id != Guid.Empty)
                    {
                        var sku = originalSku.Where(o => o.Id == item.Id).FirstOrDefault();
                        if (sku != null)
                        {
                            sku.SpaceValueid = item.Specvids;
                            sku.SpaceValueName = item.SpecvNames;
                            sku.SpceCostPrice = item.Cost;
                            sku.SpceMarketPrice = item.Price;
                            sku.SpceWeight = item.Weight;
                        }
                    }
                }
            }


            #endregion

            #region 属性
            //获取原绑定属性
            var originalAttr = _repositoryShopProductAttr.GetAll().Where(o => o.ShopProductid == id).Select(o => o.Id);
            //进行对比获取删除的属性
            var removeAttr = originalAttr.Where(o => input.Attrs.Any(s => s.Id == o) == false).ToList();
            if (removeAttr?.Count > 0)
            {
                for (int i = 0; i < removeAttr.Count; i++)
                {
                    await _repositoryShopProductAttr.DeleteAsync(removeAttr[i]);
                }
            }

            if (input.Attrs != null)
            {
                //进行比对获取新增的属性
                var addAttrs = input.Attrs.Where(o => originalAttr.Any(s => s == o.Id) == false).ToList();
                foreach (var item in addAttrs)
                {
                    if (!string.IsNullOrEmpty(item.Attrkey) && !string.IsNullOrEmpty(item.Attrvalue))
                    {
                        ShopProductAttr attr = new ShopProductAttr()
                        {
                            Id = _guid.Create(),
                            ShopProductid = id,
                            AttrKey = item.Attrkey,
                            AttrValue = item.Attrvalue
                        };

                        await _repositoryShopProductAttr.InsertAndGetIdAsync(attr);
                    }
                }
            }

            #endregion

            #region 参数
            //获取已绑定的参数
            var originalPar = _repositoryShopProductPar.GetAll().Where(o => o.ShopProductid == id).Select(o => o.Id);
            //取出上传的参数
            List<ParsValueDto> parvalues = new List<ParsValueDto>();
            if (input.ParsGroups != null)
            {
                foreach (var item in input.ParsGroups)
                {
                    parvalues.AddRange(item.ParsValues);
                }
            }

            //进行比对获取删除的绑定参数
            var removePars = originalPar.Where(o => parvalues.Any(s => s.ValueId == o) == false).ToList();
            if (removePars?.Count > 0)
            {
                for (int i = 0; i < removePars.Count; i++)
                {
                    await _repositoryShopProductPar.DeleteAsync(removePars[i]);
                }
            }

            //进行比对获取新增的绑定参数
            var addPars = parvalues.Where(o => originalPar.Any(s => s == o.ValueId) == false).ToList();
            foreach (var item in addPars)
            {
                if (!string.IsNullOrEmpty(item.ParsValue))
                {
                    ShopProductPar par = new ShopProductPar
                    {
                        Id = _guid.Create(),
                        ParKey = item.ParsKey,
                        ParValue = item.ParsValue,
                        ShopProductid = id
                    };
                    await _repositoryShopProductPar.InsertAsync(par);
                }
            }

            #endregion

            #region 标签
            if (!string.IsNullOrEmpty(input.Tags))
            {
                var tags = input.Tags.Split('|');
                var originalTag = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == id);
                var removeTags = originalTag.Where(o => tags.Any(s => new Guid(s) == o.Tagid) == false).ToList();
                if (removeTags?.Count > 0)
                {
                    for (int i = 0; i < removeTags.Count; i++)
                    {
                        await _repositoryShopProductTag.DeleteAsync(removeTags[i]);
                    }
                }

                var addTags = tags.Where(o => originalTag.Any(s => s.Tagid == new Guid(o)) == false).ToList();
                if (addTags?.Count > 0)
                {
                    foreach (var item in addTags)
                    {
                        ShopProductTag tag = new ShopProductTag
                        {
                            Id = _guid.Create(),
                            Tagid = new Guid(item),
                            ShopProductid = id,
                        };
                        await _repositoryShopProductTag.InsertAsync(tag);
                    }
                }
            }
            else
            {
                var originalTagId = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == id).Select(o => o.Id).ToList();
                if (originalTagId.Count > 0)
                {
                    for (int i = 0; i < originalTagId.Count; i++)
                    {
                        await _repositoryShopProductTag.DeleteAsync(originalTagId[i]);
                    }
                }

            }

            #endregion
        }



        /// <summary>
        /// 获取热销商品
        /// </summary>
        /// <param name="page">页数</param>
        /// <param name="pageSize">条数</param>
        /// <returns></returns>

        public async Task<IPagedList<ShopProductHotDto>> GetHotShopProduct(int page, int pageSize)
        {

            var m = _repositoryShopOrderDetails.GetAll().Join(_repositoryShopOrder.GetAll().Where(o => o.PayStatus == PayStatus.已支付), t => t.OrderId, k => k.Id, (b, n) => new
            {
                PayCount = b.ProductCount,
                ShopproductId = b.ShopproductId

            }).GroupBy(o => o.ShopproductId).Select(o => new { ShopproductId = o.Key, PayCount = o.Sum(b => b.PayCount) });

            var list = await _repositoryShopProduct.GetAll().Where(o => o.IsGrounding == true && o.ShopProductFlag != ShopProductFlag.秒杀).GroupJoin(m.DefaultIfEmpty(new { ShopproductId = Guid.Empty, PayCount = 0 }), t => t.Id, k => k.ShopproductId, (n, b) => new ShopProductHotDto
            {
                Id = n.Id,
                ImagePic = n.ImagePic,
                ProductName = n.ProductName,
                ProductNumber = n.ProductNumber,
                MarketPrice = n.MarketPrice,
                ProductDetails = n.ProductDetails,
                SpcemarketPrice = n.SpcemarketPrice,
                SpceWeight = n.SpceWeight,
                SpceIsActive = n.SpceIsActive,
                Brandid = n.Brandid,
                Unit = n.Unit,
                IsGrounding = n.IsGrounding,
                ShopTypeid = n.ShopTypeid,
                PayCount = b.FirstOrDefault().PayCount,


            }).GroupJoin(_repositoryShopProductSku.GetAll(), n => n.Id, b => b.ShopProductid, (n, b) => new ShopProductHotDto
            {

                Id = n.Id,
                ImagePic = n.ImagePic,
                ProductName = n.ProductName,
                ProductNumber = n.ProductNumber,
                MarketPrice = n.MarketPrice,
                ProductDetails = n.ProductDetails,
                SpcemarketPrice = n.SpcemarketPrice,
                SpceWeight = n.SpceWeight,
                SpceIsActive = n.SpceIsActive,
                Brandid = n.Brandid,
                Unit = n.Unit,
                IsGrounding = n.IsGrounding,
                ShopTypeid = n.ShopTypeid,
                ShopProductSkuDtos = b.MapTo<List<ShopProductSkuDto>>(),
                PayCount = n.PayCount == null ? 0 : n.PayCount,


            }).OrderByDescending(o => o.PayCount).ToPagedListAsync(page, pageSize);


            return list;

        }
        private async Task<List<ShopProductSkuDto>> GetList(Guid id)
        {
            return await _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == id).ProjectTo<ShopProductSkuDto>().ToListAsync();

        }

        [Obsolete]
        public List<ShopProductSkuDto> GetList(List<ShopProductSkuDto> list)
        {
            foreach (var item in list)
            {
                var vaids = item.SpaceValueid.Split('|');
                item.SpaceValues = _repositoryProductSpcevalue.GetAll().Where(o => vaids.Any(s => new Guid(s) == o.Id)).ProjectTo<ProductSpcevalueDto>().ToList();
            }

            return list;
        }
        /// <summary>
        /// app 得到商品详情页
        /// </summary>
        /// <param name="id">商品编号</param>
        /// <returns></returns>
        public async Task<ShopProductDetailsAppDto> GetAppDetailsShopProduct(Guid id)
        {
            var userid = AbpSession.UserId;
            if (userid.HasValue)//判断登陆
            {
                var footprint = _repositoryFootprint.GetAll().Where(o => o.UserId == userid.Value && o.ShopProductId == id && EF.Functions.DateDiffDay(o.CreationTime, DateTime.Now) == 0).FirstOrDefault();
                if (footprint == null)//判断今天是否查看过该商品
                {
                    Footprint entity = new Footprint
                    {
                        Id = _guid.Create(),
                        UserId = userid.Value,
                        ShopProductId = id,
                        CreationTime = DateTime.Now.Date,
                    };
                    await _repositoryFootprint.InsertAsync(entity);//添加一条足迹信息
                }
            }

            ShopProductDetailsAppDto dto = new ShopProductDetailsAppDto();
            var mustQuerys = new List<Func<QueryContainerDescriptor<ShopProductAppDto>, QueryContainer>>();
            mustQuerys.Add(o => o.Term(f => f.IsGrounding, true));
            mustQuerys.Add(q => q.Term(f => f.Id, id));

            var model = (await _elasticsearch.SearchAsync<ShopProductAppDto, Guid>(nameof(ShopProductAppDto).ToLower(),
            new SearchDescriptor<ShopProductAppDto>().Query(query => query.Term(f => f.IsGrounding, true) && query.Term(f => f.Id, id)), 0, 1)).Documents.FirstOrDefault();
            if (model == null)
                model = GetShopProductAppDto(id);
            ///商品基本信息
            dto.shopProductAppDto = model;
            dto.Id = id;
            ///商品评论信息
            dto.CommodityReviewsShopDetailsDtos = await _commodityReviewsAppService.GetProductShopDetailsCommodityReviewsDto(1, 15, id, null);
            ///当前购物车内总数
            dto.CarCount = _shopCarAppService.GetCarCount();
            ///当前此产品是否存在秒杀活动
            dto.ShopSecondkillDto = await _shopSecondkillAppService.GetAppByShopIdSkill(id);
            ///得到用户是否收藏过此产品
            dto.CommodityCollection = await GetCommodityCollection(id);
            dto.ShopCarCount = _shopCarAppService.GetShopCarCount(id);
            return dto;
        }

  

        #region 是否收藏
        private async Task<bool> GetCommodityCollection(Guid shopid)
        {

            if (!AbpSession.UserId.HasValue)
                return false;

            var t = await _repositoryCommodityCollection.GetAllListAsync();
            var m = t.Where(o => o.UserId == AbpSession.UserId.Value && o.ShopproductId == shopid && o.isActive == true).FirstOrDefault();
            if (m == null)
                return false;

            return true;
        }
        #endregion

        /// <summary>
        /// 搜索引擎查询数据
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <param name="ShopTypeid"></param>
        /// <param name="Brandid"></param>
        /// <param name="orderType">0 默认时间，</param>
        /// <returns></returns>

        public async Task<List<ShopProductListAppDto>> ShopSearch(SearchFilter searchFilter)
        {
            searchFilter.keyword = String.Format("{0}", searchFilter.keyword);
            SearchDescriptor<ShopProductListAppDto> tquery = new SearchDescriptor<ShopProductListAppDto>();

            ///https://www.cnblogs.com/yjf512/p/4897294.html 参考说明

            var mustQuerys = new List<Func<QueryContainerDescriptor<ShopProductListAppDto>, QueryContainer>>();
            mustQuerys.Add(o => o.Term(f => f.IsGrounding, true));
            if (!string.IsNullOrEmpty(searchFilter.keyword)) {
                // mustQuerys.Add(q => q.MultiMatch(o => o.Query(searchFilter.keyword).UseDisMax(true).Boost(2).Type(TextQueryType.BestFields).TieBreaker(0.3)));
                mustQuerys.Add(q => q.MatchPhrase(o =>o.Query(searchFilter.keyword).Field(f=>f.ProductName)));
            }
               

            if (!string.IsNullOrEmpty(searchFilter.ShopTypeid))
                mustQuerys.Add(q => q.MatchPhrase(m => m.Field(f => f.ShopTypeid).Query(searchFilter.ShopTypeid)));

            if (searchFilter.shopProductFlag != null)
                mustQuerys.Add(q => q.Term(t => t.ShopProductFlag, searchFilter.shopProductFlag));

            //tquery = tquery.Query(query => query.MultiMatch(o => o.Query(searchFilter.keyword).Type(TextQueryType.MostFields).Fields(b=>b.Field(f=>f.IsGrounding==true))));
            tquery = tquery.Query(query => query.Bool(o => o.Must(mustQuerys)));

            if (searchFilter.orderType == 0)
                tquery = tquery.Sort(o => o.Descending(t => t.CreationTime));
            if (searchFilter.orderType == 1)
                tquery = tquery.Sort(o => o.Ascending(t => t.SpcemarketPrice));
            if (searchFilter.orderType == 2)
                tquery = tquery.Sort(o => o.Descending(t => t.PayCount));
            searchFilter.page = searchFilter.page - 1;

            
            var model = await _elasticsearch.SearchAsync<ShopProductListAppDto, Guid>(nameof(ShopProductListAppDto).ToLower(), tquery, searchFilter.page, searchFilter.pageSize);
            var list = model.Documents;
            // 这里不应该处理秒杀对象体
            list.Where(o => o.ShopProductFlag == ShopProductFlag.秒杀).ToList().ForEach(async o =>
            {
                if (o.ShopProductFlag == ShopProductFlag.秒杀)
                {
                    var eventDate = new RemoteEventData(RemoteTypeHelp.TypeShopSecondkill)
                    {
                        Data = { [RemoteTypeHelp.MODELID] = o.Id }
                    };
                    await remoteEventBus.PublishAsync(RemoteTypeHelp.TOPShopSecondkill, eventDate);
                }

            });

            return await list.ToListAsync();
        }
        /// <summary>
        /// App顶级分类查询所有子类的所有商品信息
        /// </summary>
        /// <param name="searchFilter"></param>
        /// <returns></returns>
        public async Task<List<ShopProductListAppDto>> ShopTypeSearch(SearchFilter searchFilter)
        {
            var arrShopTypeguid = _repositoryShopType.GetAll().Where(o => o.ProductTypeid == Guid.Parse(searchFilter.ShopTypeid)).Select(o => o.Id).ToArray();

            searchFilter.keyword = String.Format("{0}", searchFilter.keyword);
            SearchDescriptor<ShopProductListAppDto> tquery = new SearchDescriptor<ShopProductListAppDto>();

            var mustQuerys = new List<Func<QueryContainerDescriptor<ShopProductListAppDto>, QueryContainer>>();
            mustQuerys.Add(o => o.Term(f => f.IsGrounding, true));

            if (!string.IsNullOrEmpty(searchFilter.keyword))
              mustQuerys.Add(q => q.MatchPhrase(o => o.Query(searchFilter.keyword).Field(f => f.ProductName)));
            //mustQuerys.Add(q => q.MultiMatch(o => o.Query(searchFilter.keyword).Type(TextQueryType.MostFields)));

            if (!string.IsNullOrEmpty(searchFilter.ShopTypeid))
                mustQuerys.Add(q => q.Term(t => t.ShopTypeid, arrShopTypeguid));

            if (searchFilter.shopProductFlag != null)
                mustQuerys.Add(q => q.Term(t => t.ShopProductFlag, searchFilter.shopProductFlag));

            //tquery = tquery.Query(query => query.MultiMatch(o => o.Query(searchFilter.keyword).Type(TextQueryType.MostFields).Fields(b=>b.Field(f=>f.IsGrounding==true))));
            tquery = tquery.Query(query => query.Bool(o => o.Must(mustQuerys)));

            if (searchFilter.orderType == 0)
                tquery = tquery.Sort(o => o.Descending(t => t.CreationTime));
            if (searchFilter.orderType == 1)
                tquery = tquery.Sort(o => o.Ascending(t => t.SpcemarketPrice));
            if (searchFilter.orderType == 2)
                tquery = tquery.Sort(o => o.Descending(t => t.PayCount));
            searchFilter.page = searchFilter.page - 1;
            var model = await _elasticsearch.SearchAsync<ShopProductListAppDto, Guid>(nameof(ShopProductListAppDto).ToLower(), tquery, searchFilter.page, searchFilter.pageSize);

            var list = model.Documents;
            ///这里也不应该修改秒杀对象体
            list.Where(o => o.ShopProductFlag == ShopProductFlag.秒杀).ToList().ForEach(async o =>
            {
                if (o.ShopProductFlag == ShopProductFlag.秒杀)
                {
                    var eventDate = new RemoteEventData(RemoteTypeHelp.TypeShopSecondkill)
                    {
                        Data = { [RemoteTypeHelp.MODELID] = o.Id }
                    };
                    await remoteEventBus.PublishAsync(RemoteTypeHelp.TOPShopSecondkill, eventDate);
                }

            });

            return await list.ToListAsync();
        }

        public async Task<List<ShopProductAppDto>> ShopTestSearch(SearchFilter searchFilter)
        {
            // keyword = String.Format("*{0}*", keyword);
            searchFilter.keyword = String.Format("{0}", searchFilter.keyword);
            SearchDescriptor<ShopProductAppDto> tquery = new SearchDescriptor<ShopProductAppDto>();

            var mustQuerys = new List<Func<QueryContainerDescriptor<ShopProductAppDto>, QueryContainer>>();
            mustQuerys.Add(o => o.Term(f => f.IsGrounding, true));
            if (!string.IsNullOrEmpty(searchFilter.keyword))
                mustQuerys.Add(q => q.MultiMatch(o => o.Query(searchFilter.keyword).Type(TextQueryType.MostFields)));

            if (!string.IsNullOrEmpty(searchFilter.ShopTypeid))
                mustQuerys.Add(q => q.Term(t => t.ShopTypeid, Guid.Parse(searchFilter.ShopTypeid)));

            if (searchFilter.shopProductFlag != null)
                mustQuerys.Add(q => q.Term(t => t.ShopProductFlag, searchFilter.shopProductFlag));

            //tquery = tquery.Query(query => query.MultiMatch(o => o.Query(searchFilter.keyword).Type(TextQueryType.MostFields).Fields(b=>b.Field(f=>f.IsGrounding==true))));
            tquery = tquery.Query(query => query.Bool(o => o.Must(mustQuerys)));


            if (searchFilter.orderType == 0)
                tquery = tquery.Sort(o => o.Descending(t => t.CreationTime));
            if (searchFilter.orderType == 1)
                tquery = tquery.Sort(o => o.Ascending(t => t.SpcemarketPrice));
            if (searchFilter.orderType == 2)
                tquery = tquery.Sort(o => o.Descending(t => t.PayCount));
            searchFilter.page = searchFilter.page - 1;
            var model = await _elasticsearch.SearchAsync<ShopProductAppDto, Guid>(nameof(ShopProductAppDto).ToLower(), tquery, searchFilter.page, searchFilter.pageSize);
            var list = model.Documents;

            //list.Where(o => o.ShopProductFlag == ShopProductFlag.秒杀).ToList().ForEach(async o =>
            //{
            //    if (o.ShopProductFlag == ShopProductFlag.秒杀)
            //    {
            //        if ((await _shopSecondkillAppService.GetAppByShopIdSkill(o.Id)) == null)
            //        {
            //            o.ShopProductFlag = ShopProductFlag.正常;
            //        }

            //    }

            //});

            return await list.ToListAsync();
        }
        /// <summary>
        /// 后期所有对象都改成缓存
        /// 获取一个商品对象基本信息
        /// 最终对象目前交给搜索引擎在使用
        /// </summary>
        /// <param name="id">商品id获取商品明细</param>
        /// <returns></returns>
        public ShopProductAppDto GetShopProductAppDto(Guid id)
        {

            ShopProductAppDto model = _repositoryShopProduct.Get(id).MapTo<ShopProductAppDto>();
            model.ShopProductPicDetiails = _repositoryShopProductPicDetiails.GetAll().Where(o => o.ShopProductid == id).OrderBy(o=>o.Sequence).Select(o => o.PicUrl).ToList();
            model.ShopProductPicDto = _repositoryShopProductPic.GetAll().Where(o => o.ShopProductid == id).OrderBy(o => o.Sequence).Select(o => o.PicUrl).ToList();
            model.shopProductSku = _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == id).ProjectTo<ShopProductSkuDto>().ToList();
            model.CommodityCollectionCount = _repositoryCommodityCollection.GetAll().Where(o => o.ShopproductId == id && o.isActive == true).Count();
            model.PayCount = _repositoryShopOrderDetails.GetAll().Where(o => o.ShopproductId == id && o.DeliveryStatus == DeliveryStatus.已发货 && o.Returngoods == Returngoods.未退货).Sum(o => o.ProductCount);
            model.ShopProductAttrDtos = _repositoryShopProductAttr.GetAll().Where(o => o.ShopProductid == id).ProjectTo<ShopProductAttrDto>().ToList();
            model.ShopProductParDtos = _repositoryShopProductPar.GetAll().Where(o => o.ShopProductid == id).ProjectTo<ShopProductParDto>().ToList();
            model.ShopTagDtos = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == id).Join(_repositoryShopTag.GetAll(), t => t.Tagid, k => k.Id, (t, k) => new ShopProductAppTagDto
            {
                TagName = k.TagName,
                Id = k.Id

            }).ToList();

            return model;
        }
        /// <summary>
        /// 搜索引擎查询是生成
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ShopProductListAppDto GetListAppDto(Guid id)
        {
            var entity = _repositoryShopProduct.Get(id);
            var dto = entity.MapTo<ShopProductListAppDto>();
            dto.ShopTagDtos = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == id).Join(_repositoryShopTag.GetAll(), t => t.Tagid, k => k.Id, (t, k) => new ShopProductAppTagDto
            {
                TagName = k.TagName,
                Id = k.Id
            }).ToList();
            dto.shopProductSku = _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == id).ProjectTo<ShopProductSkuDto>().ToList();
            dto.PayCount = _repositoryShopOrderDetails.GetAll().Where(o => o.ShopproductId == id && o.DeliveryStatus == DeliveryStatus.已发货 && o.Returngoods == Returngoods.未退货).Sum(o => o.ProductCount);
            return dto;

        }

        /// <summary>
        /// app用户常用清单
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<IPagedList<ShopProductListAppDto>> GetCommonList(int page, int pageSize)
        {

            var arr = _repositoryShopOrderDetails.GetAll().Where(o => o.UserId == AbpSession.UserId.Value).GroupBy(o => o.ShopproductId).Select(o => new { Id = o.Key, p = o.Sum(t => t.ProductCount) }).OrderByDescending(o => o.p).ToList().Skip(0).Take(10).Select(o => o.Id).ToArray();
            var list = await _repositoryShopProduct.GetAll().Where(o => arr.Any(b => b == o.Id)).GroupJoin(_repositoryShopOrderDetails.GetAll().Where(o => o.DeliveryStatus == DeliveryStatus.已发货 && o.Returngoods == Returngoods.未退货), k => k.Id, b => b.ShopproductId, (k, b) => new ShopProductListAppDto
            {
                Id = k.Id,
                ShopTypeid = k.ShopTypeid,
                ImagePic = k.ImagePic,
                ProductName = k.ProductName,
                MarketPrice = k.MarketPrice,
                SpceIsActive = k.SpceIsActive,
                Brandid = k.Brandid,
                Unit = k.Unit,
                IsGrounding = k.IsGrounding,
                CreationTime = k.CreationTime,
                SpcemarketPrice = k.SpcemarketPrice,
                ShopProductFlag = k.ShopProductFlag,
                PayCount = b.Sum(o => o.ProductCount)
            }).OrderByDescending(o => o.PayCount).ToPagedListAsync(page, pageSize);
            foreach (var item in list)
            {
                //item.PayCount = _repositoryShopOrderDetails.GetAll().Where(o => o.ShopproductId == item.Id && o.DeliveryStatus == DeliveryStatus.已发货 && o.Returngoods == Returngoods.未退货).Sum(o => o.ProductCount);
                item.ShopProductFlag = GetSpcemarketPrice(item.Id, item.ShopProductFlag);
                item.shopProductSku = _repositoryShopProductSku.GetAll().Where(o => o.ShopProductid == item.Id).ProjectTo<ShopProductSkuDto>().ToList();
                item.ShopTagDtos = _repositoryShopProductTag.GetAll().Where(o => o.ShopProductid == item.Id).Join(_repositoryShopTag.GetAll(), t => t.Tagid, c => c.Id, (t, c) => new ShopProductAppTagDto
                {
                    TagName = c.TagName,
                    Id = c.Id
                }).ToList();
            }
            return list;
        }
       [Obsolete]
        private decimal SpcemarketPrice(Guid id, decimal SpcemarketPrice)
        {

            var price = Task.Run(() => _shopSecondkillAppService.GetAppByShopIdSkill(id)).Result;
            if (price !=null )
                return 0;
            else
                return SpcemarketPrice;
        }

        private ShopProductFlag GetSpcemarketPrice(Guid id, ShopProductFlag flag)
        {
            var price = Task.Run(() => _shopSecondkillAppService.GetAppByShopIdSkill(id)).Result;
            if (price ==null)
                return ShopProductFlag.秒杀;
            else
                return flag;
        }
    }
}
